package com.lanyou.cook.web;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.entity.domain.DBlink;
import com.lanyou.cook.entity.domain.Field;
import com.lanyou.cook.entity.domain.FieldSystem;
import com.lanyou.cook.entity.domain.FieldSystemInterfaceCount;
import com.lanyou.cook.entity.domain.userManagement.Organization;
import com.lanyou.cook.entity.domain.userManagement.User;
import com.lanyou.cook.repository.FieldRepository;
import com.lanyou.cook.repository.FieldSystemRepository;
import com.lanyou.cook.repository.userManagement.OrganizationRepository;
import com.lanyou.cook.repository.userManagement.UserRepository;
import com.lanyou.cook.service.security.UserSessionService;
import com.lanyou.cook.util.DateUtil;
import com.lanyou.cook.web.param.FieldParam;
import com.lanyou.cook.web.param.OrganizationParam;

/**
 * 组织结构管理相关业务控制层
 * @author 曾族根
 *
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/organizations")
public class OrganizationController {
	@PersistenceContext
	private EntityManager entityManager;
	@Autowired
	private OrganizationRepository organizationRepository;
	@Autowired
	private UserRepository userRepository;

	/**
	 * 查询特定条件下的公司集合
	 * @param param	类型:FieldParam 待查询的公司参数实体
	 * @param pageable 类型:Pageable 待查询的分页参数实体
	 * @return
	 */
	@RequestMapping("/search/findByExample")
//	@RequiresPermissions(value={"fieldManagement:view","fieldManagement:maintain"},logical=Logical.OR)
	public Page<Organization> findByExample(OrganizationParam param, Pageable pageable){
		
		Specification<Organization> spec = new Specification<Organization>() {
			@Override
			public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicatesList = new ArrayList<>();
				if(StringUtils.isNotBlank(param.getName())){
					predicatesList.add(cb.like(root.get("orgName"), '%' + param.getName() + '%'));
				}
				predicatesList.add(cb.equal(root.get("level"), 1));
				query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
				return null;
			}
		};
		return organizationRepository.findAll(spec, pageable);
	}
	/**
	 * 查询特定条件下组织的集合
	 * @param param
	 * @param pageable
	 * @return
	 */
	
	@RequestMapping("/search/findByExamples")
//	@RequiresPermissions(value={"fieldManagement:view","fieldManagement:maintain"},logical=Logical.OR)
	public Page<Organization> findByExample2(OrganizationParam param, Pageable pageable){
		
		Specification<Organization> spec = new Specification<Organization>() {
			@Override
			public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicatesList = new ArrayList<>();
				if(StringUtils.isNotBlank(param.getName())){
					predicatesList.add(cb.like(root.get("orgName"), '%' + param.getName() + '%'));
				}
				if(StringUtils.isNotBlank(param.getId()))
				{
					predicatesList.add(cb.equal(root.get("parent").get("id"), param.getId()));
				}
				predicatesList.add(cb.equal(root.get("level"), 2));
				query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
				return null;
			}
		};
		return organizationRepository.findAll(spec, pageable);
	}
	//查询是否可以重名
	@RequestMapping(value = "/search/checkIsCanSave", produces = "application/json")
	public String checkIsCanSave(String name,String originalId,String parent,String level) {
		int i=Integer.parseInt(level);
		if(i==1){//公司维护
			Organization organization = organizationRepository.findByOrgNameAndLevel(name,i);
			if (organization != null) {
				if (!StringUtils.equals(organization.getId(), originalId)) {
					JsonObject result = new JsonObject();
					result.addProperty("isCanSave", false);
					result.addProperty("errorCode", "DUPLICATE");
					return result.toString();
				}
			}
		}else{//部门维护
			Organization org=organizationRepository.findByOrgNameAndLevel(parent, 1);
			Organization organization = organizationRepository.findByOrgNameAndParent(name,org.getId());
			if (organization != null) {
				if (!StringUtils.equals(organization.getId(), originalId)) {
					JsonObject result = new JsonObject();
					result.addProperty("isCanSave", false);
					result.addProperty("errorCode", "DUPLICATE");
					return result.toString();
				}
			}
		}
		
		JsonObject result = new JsonObject();
		result.addProperty("isCanSave", true);
		return result.toString();
	}
	
	//判断公司下是否存在部门
	@RequestMapping(value="/company/checkIsCanDelete", produces="application/json")
	public String checkIsCanDelete(String id,String level){
		JsonObject result = new JsonObject();
		if(StringUtils.equals(level, "1")){
			long count = organizationRepository.countByParent_id(id);
			
			if(count > 0){
				result.addProperty("isCanDelete", false);
				result.addProperty("reason", "该公司下存在部门系统，不能删除");
				return result.toString();
			} else {
				result.addProperty("isCanDelete", true);
				return result.toString();
			}
		}else{
			List<User> user = userRepository.findByOrganization_Id(id);
			if(user.size()>0){
				result.addProperty("isCanDelete", false);
				result.addProperty("reason", "该部门下存在用户，不能删除");
				return result.toString();
			}else{
				result.addProperty("isCanDelete", true);
				return result.toString();
			}
		}
	}
	
	
}